using System;
using System.Collections;
using System.Text;

using log4net;
using log4net.Config;

using MySql.Data.MySqlClient;
using Chat.metier;
using ChatServer;
using NHibernate;
using NHibernate.Expression;
using Iesi.Collections;

namespace Chat.dao
{
    class UserDAO : IUserDAO
    {
        private static readonly ILog log = LogManager.GetLogger(typeof(UserDAO));

        #region IUserDAO Membres
        /// <summary>
        /// Retourne un user en fonction de son id
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public User getById(int id)
        {
            ISession session = InitFramework.sessionFactory.OpenSession();
            try
            {
                User user = (User)session.Get(typeof(User), id);
                session.Close();
                return user;
            }
            catch (Exception e)
            {
                log.Error("User getById ", e);
                return null;
            }
        }

        /// <summary>
        /// Retourne tous les utilisateurs
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public IList getAll()
        {
            ISession session = InitFramework.sessionFactory.OpenSession();
            try
            {
                IList users = session.CreateQuery("from User").List();
                session.Close();
                return users;
            }
            catch (Exception e)
            {
                log.Error("User getAll ", e);
                return null;
            }
        }


        public int save(User user)
        {
            ISession session = InitFramework.sessionFactory.OpenSession();
            try
            {
                ITransaction tx = session.BeginTransaction();
                int id = (int)session.Save((Object)user);
                tx.Commit();
                session.Close();
                return id;
            }
            catch (Exception e)
            {
                log.Error("User save ", e);
                return 0;
            }
        }

        public bool login_exist(String login)
        {
            ISession session = InitFramework.sessionFactory.OpenSession();
            ICriteria crit = session.CreateCriteria(typeof(User));
            crit.Add(Expression.Eq("Login", login));
            try
            {
                if (0 == crit.List().Count)
                {
                    session.Close();
                    return false;
                }
                else
                {
                    session.Close();
                    return true;
                }
            }
            catch (Exception e)
            {
                log.Error("User Login existe ", e);
                return true;
            }
        }

        /// <summary>
        /// Return the user's id else if false 0
        /// </summary>
        /// <param name="login"></param>
        /// <param name="passwd"></param>
        /// <returns></returns>
        public User login(String login, String passwd)
        {
            ISession session = InitFramework.sessionFactory.OpenSession();
            ICriteria crit = session.CreateCriteria(typeof(User));
            crit.Add(Expression.Eq("Login", login));
            crit.Add(Expression.Eq("Passwd", passwd));
            try
            {
                if (0 == crit.List().Count)
                {
                    session.Close();
                    return null;
                }
                else
                {
                    return ((User)crit.UniqueResult());
                }
            }
            catch (Exception e)
            {
                log.Error("User login", e);
                return null;
            }
        }

        public ISet getContacts(int id)
        {
            try
            {
                User u = this.getById(id);
                return (ISet)u.Contacts;
            }
            catch (Exception e)
            {
                log.Error("User contacts", e);
                return null;
            }
        }

        public ISet getContacts(User user)
        {
            try
            {
                return (ISet)user.Contacts;
            }
            catch (Exception e)
            {
                log.Error("User contacts", e);
                return null;
            }
        }

        public bool addContact(int id, String login)
        {
            User u = this.getById(id);

            // Init session
            ISession session = InitFramework.sessionFactory.OpenSession();

            try
            {
                // Search User with this login
                ICriteria crit2 = session.CreateCriteria(typeof(User));
                crit2.Add(Expression.Eq("Login", login));
                User u2 = (User)crit2.UniqueResult();

                // Creation and save the contact
                Contact c = new Contact();
                Contact d = new Contact();
                //
                c.User = u;
                c.ContactUser = u2;
                //
                d.User = u2;
                d.ContactUser = u;
                //
                ContactDAO cDAO = new ContactDAO();
                cDAO.save(c);
                cDAO.save(d);
                session.Close();
                return true;
            }

            catch (Exception e)
            {
                log.Error("User addContact", e);
                return false;
            }
        }
        /// <summary>
        /// Delete a contact for the User
        /// </summary>
        /// <param name="idUser"></param>
        /// <param name="idContact"></param>
        /// <returns></returns>
        public bool deleteContact(int idUser, int idContact)
        {
            User u = this.getById(idUser);
            User u2 = this.getById(idContact);
            // Init session
            ISession session = InitFramework.sessionFactory.OpenSession();
            try
            {
                ITransaction tx = session.BeginTransaction();

                // Search the User with this Id
                ICriteria crit3 = session.CreateCriteria(typeof(Contact));
                crit3.Add(Expression.Eq("User", u));
                crit3.Add(Expression.Eq("ContactUser", u2));
                Contact c = (Contact)crit3.UniqueResult();
                session.Delete((Object)c);
                tx.Commit();
                session.Close();
                return true;
            }
            catch (Exception e)
            {
                log.Error("User deleteContact", e);
                return false;
            }
        }

        public User getByLogin(string login)
        {
            ISession session = InitFramework.sessionFactory.OpenSession();

            try
            {
                ICriteria crit2 = session.CreateCriteria(typeof(User));
                crit2.Add(Expression.Eq("Login", login));
                User u2 = (User)crit2.UniqueResult();
                return u2;
            }
            catch (Exception e)
            {
                log.Error("User deleteContact", e);
                return null;
            }
        }

        #endregion
    }
}
